using bdddoc.core;
using jpboodhoo.bdd;
using jpboodhoo.bdd.contexts;
using jpboodhoo.bdd.mbunit;
using jpboodhoo.bdd.mbunit.standard.observations;
using resharperupdate.core.dto;
using resharperupdate.core.dto.impl;
using resharperupdate.core.services;
using resharperupdate.core.services.impl;
using Rhino.Mocks;

namespace resharperupdate.core.tests.services
{
    public class UpdaterTaskSpecs
    {
        [Concern(typeof(UpdaterTask))]
        public abstract class concerns : observations_for_a_sut_with_a_contract<IUpdaterTask, UpdaterTask>
        {
            protected static IRegistryLookup registry_lookup;
            protected static IDownloader downloader;
            protected static INightlyBuildParser nightly_build_parser;
            protected static IProductVersionParser version_parser;

            context c = () =>
                                    {
                                        registry_lookup = the_dependency<IRegistryLookup>();
                                        downloader = the_dependency<IDownloader>();
                                        version_parser = the_dependency<IProductVersionParser>();
                                        nightly_build_parser = the_dependency<INightlyBuildParser>();
                                    };

        }

        public class when_checking_if_a_new_version_exists : concerns
        {
            static bool result;
            static string registry_version;
            static string html;

            context c = () =>
                            {
                                
                                registry_version = "4.5.1711.21";
                                var build = new Build {Date = "07 Feb 2009",Number = 1712,Url = "download url"};
                                html = "nightly builds";
                                registry_lookup.Stub(x => x.version()).Return(registry_version);
                                version_parser.Stub(x => x.build(registry_version)).Return(1711);
                                downloader.Stub(x => x.nightly_html()).Return(html);
                                nightly_build_parser.Stub(x => x.parse(html)).IgnoreArguments().Return(build);                                
                            };

            because b = () => result = sut.is_update_available();

            it should_know_there_is_an_update = () => result.should_be_true();
            it should_check_the_version_in_registry = () => registry_lookup.was_told_to(x => x.version());
            it should_extract_the_version_number_from_product_version =
                () => version_parser.was_told_to(x => x.build(registry_version));
            it should_download_the_nightly_builds = () => downloader.was_told_to(x => x.nightly_html());
            it should_find_the_latest_build_from_html = () => nightly_build_parser.was_told_to(x => x.parse(html));            
        }
 
        public class when_downloading_the_latest_version : concerns
        {
            static IBuild result;
            static string registry_version;
            static string html;
            static Build build;
           
            context c = () =>
                            {
                                
                                registry_version = "4.5.1711.21";
                                build = new Build {Date = "07 Feb 2009",Number = 1712,Url = "download url"};
                                html = "nightly builds";
                                registry_lookup.Stub(x => x.version()).Return(registry_version);
                                version_parser.Stub(x => x.build(registry_version)).Return(1711);
                                downloader.Stub(x => x.nightly_html()).Return(html);
                                nightly_build_parser.Stub(x => x.parse(html)).IgnoreArguments().Return(build);                                
                            };

            because b = () => result = sut.latest_version();

            it should_know_there_is_an_update = () => result.Number.should_be_equal_to(build.Number);
            it should_check_the_version_in_registry = () => registry_lookup.was_told_to(x => x.version());
            it should_extract_the_version_number_from_product_version =
                () => version_parser.was_told_to(x => x.build(registry_version));
            it should_download_the_nightly_builds = () => downloader.was_told_to(x => x.nightly_html());
            it should_find_the_latest_build_from_html = () => nightly_build_parser.was_told_to(x => x.parse(html));
        }

    }
}